package com.urbanski.clipboard.client;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import org.apache.log4j.Logger;
import com.urbanski.clipboard.common.message.Message;
import com.urbanski.clipboard.common.message.Response;

public class ServerConnection
{
	private static final Logger LOGGER = Logger.getLogger(ServerConnection.class);

	private Socket serverSocket;
	private String hostname;
	private int port;
	private String alias;
	private ObjectInputStream inputStream;
	private ObjectOutputStream outputStream;
	private boolean paused = false;

	public ServerConnection(String hostname, int port)
	{
		this(hostname, port, null);
	}

	public ServerConnection(String hostname, int port, String alias)
	{
		this.hostname = hostname;
		this.port = port;
		this.alias = alias;
	}

	public synchronized void connect() throws UnknownHostException, IOException
	{
		serverSocket = new Socket(hostname, port);
		outputStream = new ObjectOutputStream(serverSocket.getOutputStream());
		outputStream.writeObject(ClipboardClient.getClientName());
		outputStream.flush();
		inputStream = new ObjectInputStream(serverSocket.getInputStream());
	}

	public synchronized void sendData(String data)
	{
		System.out.println("Sending clipboard data: " + data);
	}

	public synchronized Response sendMessage(Message message) throws IOException
	{
		outputStream.writeObject(message);
		outputStream.flush();
		try
		{
			Object o = inputStream.readObject();
			LOGGER.debug("Response type received: " + o.getClass());
			if (o instanceof Response)
			{
				return (Response)o;
			}

		}
		catch (ClassNotFoundException e)
		{
			LOGGER.error("Unknown response received: ", e);
		}

		return null;
	}

	public synchronized String getHostname()
	{
		return hostname;
	}

	public synchronized int getPort()
	{
		return port;
	}

	public synchronized String getAlias()
	{
		return alias;
	}

	public synchronized void setAlias(String alias)
	{
		this.alias = alias;
	}

	public synchronized boolean isPaused()
	{
		return paused;
	}

	public synchronized void setPaused(boolean paused)
	{
		this.paused = paused;
	}

	public synchronized boolean equals(Object o)
	{
		if (!(o instanceof ServerConnection))
		{
			return false;
		}

		ServerConnection s = (ServerConnection)o;
		return hostname.equals(s.hostname);
	}

	public synchronized int hashCode()
	{
		return hostname.hashCode();
	}

	public synchronized void close()
	{
		try
		{
			serverSocket.close();
		}
		catch (IOException e)
		{
			LOGGER.error("Error closing server connection " + hostname, e);
		}
	}
}
